package com.moon.admin.tools.servcie;

import java.io.IOException;
import java.io.StringWriter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.IOUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.moon.admin.framework.util.MoonException;
import com.moon.admin.tools.entity.GenTable;
import com.moon.admin.tools.entity.GenTableColumn;
import com.moon.admin.tools.mapper.GenTableMapper;
import com.moon.admin.tools.utils.VelocityUtils;
import com.moon.admin.tools.domain.TableListQueryVO;

import lombok.extern.slf4j.Slf4j;

/**
 * 业务 服务层实现
 *
 * @author moon
 */
@Service
@Slf4j
public class GenTableService extends ServiceImpl<GenTableMapper,GenTable> {

    @Autowired
    private GenTableColumnService genTableColumnService;

    /**
     * 查询据库列表
     *
     * @param tableListQueryVO 业务信息
     * @return 数据库表集合
     */
    public List<GenTable> selectDbTableList(IPage<GenTable> page, TableListQueryVO tableListQueryVO) {
        return this.baseMapper.selectDbTableList(page,tableListQueryVO);
    }

    /**
     * 修改业务
     *
     * @param genTable 业务信息
     * @return 结果
     */
    @Transactional(rollbackFor = MoonException.class)
    public void editSave(GenTable genTable) {
        List<GenTableColumn> columns = genTable.getColumns();
        if(columns==null){
            throw new MoonException("表【"+genTable.getTableName()+"】沒有字段");
        }
        this.saveOrUpdate(genTable);
        genTableColumnService.remove(Wrappers.<GenTableColumn>lambdaQuery().eq(GenTableColumn::getTableId, genTable.getId()));
        List<GenTableColumn> addColumns = Lists.newArrayList();
        columns.forEach(entity->{
            entity.setTableId(genTable.getId());
            entity.setId(null);
            addColumns.add(entity);
        });
        if(addColumns.size()>0){
            genTableColumnService.saveBatch(addColumns);
        }
    }

    /**
     * 预览代码
     * @param tableId 表编号
     * @return 预览数据列表
     */

    public Map<String, String> previewCode(Integer tableId) {
        Map<String, String> dataMap = new LinkedHashMap<>();
        // 查询表信息
        GenTable table = this.getById(tableId);
        // 查询列信息
        List<GenTableColumn> columns = genTableColumnService.list(Wrappers.<GenTableColumn>lambdaQuery().eq(GenTableColumn::getTableId,tableId));
        table.setColumns(columns);
        VelocityUtils.initVelocity();
        VelocityContext context = VelocityUtils.prepareContext(table);
        // 获取模板列表
        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
        for (String template : templates) {
            // 渲染模板
            StringWriter sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template,"UTF-8");
            tpl.merge(context, sw);
            dataMap.put(template, sw.toString());
        }
        return dataMap;
    }

    /**
     * 查询表信息并生成代码
     */
    public void generatorCode(Integer id, ZipOutputStream zip) {
        // 查询表信息
        GenTable table = this.getById(id);
        // 查询列信息
        List<GenTableColumn> columns = genTableColumnService.list(Wrappers.<GenTableColumn>lambdaQuery().eq(GenTableColumn::getTableId,id));
        table.setColumns(columns);
        VelocityUtils.initVelocity();
        VelocityContext context = VelocityUtils.prepareContext(table);
        // 获取模板列表
        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
        for (String template : templates) {
            // 渲染模板
            StringWriter sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template, "UTF-8");
            tpl.merge(context, sw);
            try {
                // 添加到zip
                zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
                IOUtils.write(sw.toString(), zip, "UTF-8");
                IOUtils.closeQuietly(sw);
                zip.flush();
                zip.closeEntry();
            } catch (IOException e) {
                log.error("渲染模板失败，表名：" + table.getTableName(), e);
            }
        }
    }
}